package jfox.platform.function.dao;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.QueryHint;

import jfox.platform.function.entity.Node;
import jfox.platform.infrastructure.EntityObject;
import jfox.platform.infrastructure.SuperDAO;

/**
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */
@Stateless
@Local
@NamedNativeQueries(
        {
        @NamedNativeQuery(
                name = NodeDAOBean.GET_NODE_BY_ID,
                query = "SELECT * FROM T_SYS_NODE WHERE ID=$ID AND VSTATUS=" + EntityObject.VSTATUS_NORMAL,
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }
        ),
        @NamedNativeQuery(
                name = NodeDAOBean.GET_MODOULE_NODES,
                query = "SELECT * FROM T_SYS_NODE WHERE ROOT_ID=0 AND VSTATUS=" + EntityObject.VSTATUS_NORMAL + " ORDER BY PRIORITY",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),

        @NamedNativeQuery(
                name = NodeDAOBean.GET_NODE_BY_BIND_ACTION,
                query = "SELECT * FROM T_SYS_NODE WHERE BIND_ACTION=$BIND_ACTION AND VSTATUS=" + EntityObject.VSTATUS_NORMAL,
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }
        ),

        @NamedNativeQuery(
                name = NodeDAOBean.GET_ALL_NODES,
                query = "SELECT * FROM T_SYS_NODE WHERE VSTATUS != " + EntityObject.VSTATUS_REMOVED + " ORDER BY ID",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }
        ),
        @NamedNativeQuery(
                name = NodeDAOBean.GET_NODES_BY_ROOT_ID,
                query = "SELECT * FROM T_SYS_NODE WHERE ROOT_ID=$ROOT_ID AND VSTATUS=" + EntityObject.VSTATUS_NORMAL + " ORDER BY PRIORITY",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.GET_MENU_NODES_BY_ROOT_ID,
                query = "SELECT * FROM T_SYS_NODE WHERE ROOT_ID=$ROOT_ID AND TYPE=0 AND VSTATUS=" + EntityObject.VSTATUS_NORMAL + " ORDER BY PRIORITY",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.GET_CHILD_NODES,
                query = "SELECT * FROM T_SYS_NODE WHERE PARENT_ID=$PARENT_ID AND VSTATUS=" + EntityObject.VSTATUS_NORMAL + " ORDER BY PRIORITY",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.GET_BUTTON_CHILD_NODES,
                query = "SELECT * FROM T_SYS_NODE WHERE PARENT_ID=$PARENT_ID AND TYPE=1 AND VSTATUS =" + EntityObject.VSTATUS_NORMAL + " ORDER BY PRIORITY",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.INSERT_NODE,
                query = "INSERT INTO T_SYS_NODE(" +
                        "ID," +
                        "NAME, " +
                        "LOCAL_NAME, " +
                        "PRIORITY, " +
                        "CREATE_TIME, " +
                        "CREATOR, " +
                        "LAST_MODIFIED, " +
                        "LAST_MODIFIER, " +
                        "VSTATUS, " +
                        "DESCRIPTION, " +
                        "REFS, " +
                        "ROOT_ID," +
                        "PARENT_ID," +
                        "BIND_ACTION, " +
                        "TYPE," +
                        "CRUD," +
                        "NODE_GROUP," +
                        "ICON) " +
                        "VALUES (" +
                        "$NODE.getId()," +
                        "$NODE.getName()," +
                        "$NODE.getLocalName()," +
                        "$NODE.getPriority()," +
                        "$NODE.getCreateTime()," +
                        "$NODE.getCreator()," +
                        "$NODE.getLastModified()," +
                        "$NODE.getLastModifier()," +
                        "$NODE.getVstatus()," +
                        "$NODE.getDescription()," +
                        "$NODE.getRefs()," +
                        "$NODE.getRootId()," +
                        "$NODE.getParentId()," +
                        "$NODE.getBindAction()," +
                        "$NODE.getType()," +
                        "$NODE.getCrud()," +
                        "$NODE.getNodeGroup()," +
                        "$NODE.getIcon())",
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.DELETE_NODE,
                query = "UPDATE T_SYS_NODE SET VSTATUS = " + EntityObject.VSTATUS_REMOVED + " WHERE ID=$ID",
                resultClass = Node.class,
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        ),
        @NamedNativeQuery(
                name = NodeDAOBean.UPDATE_NODE,
                query = "UPDATE T_SYS_NODE" +
                        " SET NAME = " + "$NODE.getName()," +
                        " LOCAL_NAME = " + "$NODE.getLocalName()," +
                        " PRIORITY = " + "$NODE.getPriority()," +
                        " CREATE_TIME = " + "$NODE.getCreateTime()," +
                        " CREATOR = " + "$NODE.getCreator()," +
                        " LAST_MODIFIED = " + "$NODE.getLastModified()," +
                        " LAST_MODIFIER = " + "$NODE.getLastModifier()," +
                        " VSTATUS = " + "$NODE.getVstatus()," +
                        " DESCRIPTION = " + "$NODE.getDescription()," +
                        " REFS = " + "$NODE.getRefs()," +
                        " ROOT_ID = " + "$NODE.getRootId()," +
                        " PARENT_ID = " + "$NODE.getParentId()," +
                        " BIND_ACTION = " + "$NODE.getBindAction()," +
                        " TYPE = " + "$NODE.getType()," +
                        " CRUD = " + "$NODE.getCrud()," +
                        " NODE_GROUP = " + "$NODE.getNodeGroup()," +
                        " ICON = " + "$NODE.getIcon()" +
                        " WHERE ID=" + "$NODE.getId()",
                hints = {
                @QueryHint(name = "cache.partition", value = "function")
                        }

        )

                }
)

public class NodeDAOBean extends SuperDAO implements NodeDAO {

    public final static String GET_NODE_BY_ID = "NodeDAOBean.getNodeById";
    public final static String GET_NODE_BY_BIND_ACTION = "NodeDAOBean.getNodeByBindAction";
    public final static String GET_ALL_NODES = "NodeDAOBean.getAllNodes";
    public final static String GET_MENU_NODES_BY_ROOT_ID = "NodeDAOBean.getMenuNodesByModuleId";
    public final static String GET_NODES_BY_ROOT_ID = "NodeDAOBean.getNodesByModuleId";
    public final static String GET_CHILD_NODES = "NodeDAOBean.getChildNodes";
    public final static String GET_BUTTON_CHILD_NODES = "NodeDAOBean.getButtonChildNodes";
    public final static String INSERT_NODE = "NodeDAOBean.insertNode";
    public final static String DELETE_NODE = "NodeDAOBean.deleteNode";
    public final static String UPDATE_NODE = "NodeDAOBean.updateNode";
    public final static  String GET_MODOULE_NODES = "NodeDAOBean.getModuleNodes";


    public void insertNode(Node node) {
        Map<String, Object> params = new HashMap<String, Object>(1);
        params.put("NODE", node);
        executeNamedNativeUpdate(INSERT_NODE, params);
    }

    public int deleteNode(long id) {
/*
        Map<String, Object> params = new HashMap<String, Object>(1);
        params.put("ID", id);
        return executeNamedNativeUpdate(NodeDAOBean.DELETE_NODE, params);
*/
        return deleteEntityObjectByColumn(DELETE_NODE,"ID",id);
    }

    public int updateNode(Node node) {
        Map<String, Object> params = new HashMap<String, Object>(1);
        params.put("NODE", node);
        return executeNamedNativeUpdate(UPDATE_NODE, params);
    }

    public Node getNodeById(long id) {
        return (Node)getEntityObjectByColumn(GET_NODE_BY_ID, "ID", id);
    }

    public List<Node> getModuleNodes() {
        return (List<Node>)processNamedNativeQuery(GET_MODOULE_NODES, null);
    }

    public Node getNodeByBindAction(String bindAction) {
        return (Node)getEntityObjectByColumn(NodeDAOBean.GET_NODE_BY_BIND_ACTION, "BIND_ACTION", bindAction);
    }

    public List<Node> getMenuNodesByModuleId(long moduleId) {
        Map<String, Object> params = new HashMap<String, Object>(1);
        params.put("ROOT_ID", moduleId);
        return (List<Node>)processNamedNativeQuery(GET_MENU_NODES_BY_ROOT_ID, params);
    }

    public List<Node> getAllNodes() {
        return (List<Node>)processNamedNativeQuery(GET_ALL_NODES, Collections.EMPTY_MAP);
    }

    public List<Node> getNodesByModuleId(long moduleId) {
        Map<String, Long> params = new HashMap<String, Long>(1);
        params.put("ROOT_ID", moduleId);
        return (List<Node>)processNamedNativeQuery(GET_NODES_BY_ROOT_ID, params);
    }


    public List<Node> getButtonChildNodes(long parentNodeId) {
        Map<String, Long> params = new HashMap<String, Long>(1);
        params.put("PARENT_ID", parentNodeId);
        return (List<Node>)processNamedNativeQuery(GET_BUTTON_CHILD_NODES, params);
    }

    public List<Node> getChildNodes(long parentNodeId) {
        Map<String, Long> params = new HashMap<String, Long>(1);
        params.put("PARENT_ID", parentNodeId);
        return (List<Node>)processNamedNativeQuery(GET_CHILD_NODES, params);
    }

}
